package com.ncepu.clubmanagement.service.impl;

import com.ncepu.clubmanagement.anno.CommitteePermission;
import com.ncepu.clubmanagement.mapper.*;
import com.ncepu.clubmanagement.pojo.*;
import com.ncepu.clubmanagement.service.ClubService;
import com.ncepu.clubmanagement.service.UploadAssist.FileUrlProvider;
import com.ncepu.clubmanagement.service.UploadAssist.FileUrlUpdater;
import com.ncepu.clubmanagement.service.UploadService;
import com.ncepu.clubmanagement.utils.PageDivideUtil;
import com.ncepu.clubmanagement.utils.PageDivideUtilAssist;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class ClubServiceImpl implements ClubService {

    @Autowired
    private AffairsMapper affairMapper;

    @Autowired
    private PersonMapper personMapper;

    @Autowired
    private ClubInfoMapper clubInfoMapper;

    @Autowired
    private ClubManagementRelationMapper clubManagementRelationMapper;

    @Autowired
    private ClubSelectionMapper clubSelectionMapper;

    @Autowired
    private UploadService uploadService;


    @Override
    @Transactional
    public void addClub(ClubAdd clubAdd) {
        // 定义好Club
        Club club = clubAdd.toClub(() -> {
            // 这个函数式方法返回具体的俱乐部对应的学校id
            return personMapper.selectSchIdByPersonId(clubAdd.getPersonId());
        });
        // 添加Club到对应表中
         clubInfoMapper.addClubInfo(club);
        // 添加管理员信息
        clubManagementRelationMapper.addClubManager(clubAdd.getPersonId(), club.getClubId());
    }

    @Override
    public PageBean getClub(Integer page, Integer pageSize, String clubName) {

        // 使用工具方法简化操作
        PageBean pageBean = PageDivideUtil.toPageBean(() -> clubInfoMapper.getClubByClubName(clubName),
                page, pageSize);

//        PageHelper.startPage(page, pageSize);
//        List<Club> ls = clubInfoMapper.getClubByClubName(clubName);
//
//
//        Page<Club> p = (Page<Club>)ls;
//        PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
        return pageBean;
    }

    @Override
    @Transactional
    public void addPersonToClub(ClubSelection clubSelection) {
        // 添加人员到社团
        clubSelectionMapper.addClubSelection(clubSelection);
        // 社团表中number字段相应值加1
        clubInfoMapper.addNumberByClubId(clubSelection.getClubId());

    }

    @Override
    public void removePersonFromClub(ClubSelection clubSelection) {
        // 删除人员从社团
        clubSelectionMapper.deleteClubSelection(clubSelection);
        // 社团表中number字段相应值减1
        clubInfoMapper.subNumberByClubId(clubSelection.getClubId());
    }

    @Override
    public PageBean getJoinedClub(Integer page, Integer pageSize, String clubName, Integer personId) {

        PageBean pageBean = PageDivideUtil.toPageBean
                ((PageDivideUtilAssist<Club>) () -> clubInfoMapper.getJoinedClubByClubNameAndPersonId(clubName, personId)
                , page, pageSize);

//        PageHelper.startPage(page, pageSize);
//        List<Club> ls = clubInfoMapper.getJoinedClubByClubNameAndPersonId(clubName,personId);
//
//
//        Page<Club> p = (Page<Club>)ls;
//        PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
        return pageBean;
    }

    @Override
    public PageBean getManagedClub(Integer page, Integer pageSize, String clubName, Integer personId) {
        PageBean pageBean = PageDivideUtil.toPageBean
                ((PageDivideUtilAssist<Club>) () -> clubInfoMapper.getManagedClubByClubNameAndPersonId(clubName, personId)
                        , page, pageSize);
//        PageHelper.startPage(page, pageSize);
//        List<Club> ls = clubInfoMapper.getManagedClubByClubNameAndPersonId(clubName,personId);
//
//
//        Page<Club> p = (Page<Club>)ls;
//        PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
        return pageBean;
    }

    @Override
    public boolean isJoinedOrManaged(Integer personId,Integer clubId){
        Boolean isManaged =  clubManagementRelationMapper.isPersonIdExistByClubId(clubId,personId);
        Boolean isJoined = clubSelectionMapper.getPersonIdByClubId(clubId).contains(personId);
        return isManaged || isJoined;

    }

    @Override
    public boolean isJoined(Integer personId, Integer clubId) {
        return clubSelectionMapper.getPersonIdByClubId(clubId).contains(personId);
    }

    @Override
    public  boolean isManaged(Integer personId, Integer clubId) {
        return clubManagementRelationMapper.isPersonIdExistByClubId(clubId,personId);
    }

    @Override
    @CommitteePermission  // 权限要求
    public void updateClubInfoByURL(ClubModify clubModify) throws Exception {
        // 先解析原本的URL，解析完成后再调用后面的方法(注意：源和目的的URL要位于同一逻辑位置（比如都在同一OSS服务器中）)
        String url  = clubModify.getBackImage();
        MultipartFile file = null;
        // 判定url非空，即存在文件替换需求
        if (url != null && !url.isEmpty()) {
            // 执行文件替换逻辑代码
            uploadService.universalMoveFile(Integer.toString(clubModify.getClubId()), "clubBackImage", url
                    , (FileUrlProvider) () -> clubInfoMapper.getClubBackImageByClubId(clubModify.getClubId()),
                    (FileUrlUpdater) url1 -> clubInfoMapper.updateClubBackImageByClubId(url1, clubModify.getClubId()),
                    "clubBackImage");
        }
        // 替换完毕或根本不存在文件替换需求，执行其它信息更新逻辑
        updateClubInfoOtherInfo(clubModify);
    }

    @Override
    @CommitteePermission  // 权限要求
    public void updateClubInfo(ClubModify clubModify, MultipartFile file) throws Exception {
        if(file != null && !file.isEmpty()) {
            // 更新图片信息
            uploadService.universalUploadFile(Integer.toString(clubModify.getClubId()), "clubBackImage", file
                    , (FileUrlProvider) () -> clubInfoMapper.getClubBackImageByClubId(clubModify.getClubId()),
                    (FileUrlUpdater) url -> clubInfoMapper.updateClubBackImageByClubId(url, clubModify.getClubId()),
                    "clubBackImage");
        }
        // 插入其它信息
        updateClubInfoOtherInfo(clubModify);
    }

    @Transactional
    public void updateClubInfoOtherInfo(ClubModify clubModify){
        // 插入其它信息
        if(clubModify.getClubName() != null || clubModify.getIntroduction() != null
        || clubModify.getClubState() != null || clubModify.getClubLevel() != null
        ) {
            clubInfoMapper.updateClubInfo(clubModify);
        }
        if(clubModify.getManagerId() != null){
            clubManagementRelationMapper.changeClubManagerIdByClubId(clubModify.getManagerId(), clubModify.getClubId());
        }
    }

    @Override
    public List<Club> getJoinedClubWithoutPage(String clubName, Integer personId) {
        List<Club> ls = clubInfoMapper.getJoinedClubByClubNameAndPersonId(clubName,personId);
        List<Club> ls2 = clubInfoMapper.getManagedClubByClubNameAndPersonId(clubName, personId);
        List<Club> combinedList = Stream.concat(ls.stream(), ls2.stream())
                .toList();

        return combinedList;
    }

    @Override
    public List<Club> getManagedClubWithoutPage(String clubName, Integer personId) {
        List<Club> ls = clubInfoMapper.getManagedClubByClubNameAndPersonId(clubName,personId);
        return ls;
    }

    public List<Integer> getManagedClubIdWithoutPage(String clubName, Integer personId){
        List<Integer> ls = clubInfoMapper.getManagedClubIdByClubNameAndPersonId(clubName,personId);
        return ls;
    }

    @Override
    public ClubChangeableInfoWithManager getClubChangeableInfoWithoutManager(Integer clubId) {
        return clubInfoMapper.getClubChangeableInfoMapperByClubId(clubId);
    }

    @Override
    public boolean checkIsManagedInClub(Integer sourcePersonId, Integer targetPersonId) {
        Boolean isManageInCLub = clubManagementRelationMapper.
                isExistBySourcePersonIdAndTargetPersonId(sourcePersonId, targetPersonId);
        return isManageInCLub;
    }

    @Override
    @Transactional
    public void deleteClub(Integer clubId) {
        // 1. 删除社团依赖关系
        clubManagementRelationMapper.deleteClubManagerByClubId(clubId);
        clubSelectionMapper.deleteClubSelectionByClubId(clubId);
        // 2. 删除社团信息
        // 2.1 先获取到社团信息的备份以便后续处理
        ClubChangeableInfoWithManager resource = clubInfoMapper.getClubChangeableInfoMapperByClubId(clubId);
        String url = resource.getBackImage();
        // 2.2 删除社团信息
        clubInfoMapper.deleteClubInfoByClubId(clubId);
        // 3. 删除社团的url资源(主要是图片等)
        // 注意：文章资源不删除！
        uploadService.deleteUrlResourceNotInTable(url);
    }
}
